home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mm / ccmd / cursor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  4.6 KB  |  243 lines

  1. /*
  2.  Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  the City of New York.  Permission is granted to any individual or
  4.  institution to use, copy, or redistribute this software so long as it
  5.  is not sold for profit, provided this copyright notice is retained.
  6.  
  7.  Authors: Howie Kaye
  8. */
  9.  
  10. /*
  11.  * cursor control
  12.  * handle cursor motion and line updating for command line editing.
  13.  */
  14.  
  15.  
  16. #include "ccmdlib.h"
  17. #include "cmfncs.h"
  18.  
  19. int *
  20. go_from(p1,p2) 
  21. int *p1, *p2;
  22. {
  23.     int l,c;
  24.  
  25.     if (p1 != p2) {
  26.     relcharpos(&l,&c,p1,p2);
  27.     if (l > 0)
  28.         go_down_line(l);
  29.     else
  30.         go_up_line(-l);
  31.     if (c > 0)
  32.         go_forward(c);
  33.     else
  34.         go_backward(-c);
  35.     }
  36.     return(p2);
  37. }
  38.  
  39. int *
  40. goto_end_of_line()
  41. {
  42.   int *p = cmcsb._cmcur;
  43.   int i=0;
  44.   int l,c;
  45.  
  46.   while(p < cmcsb._cmptr + cmcsb._cminc && ((*p & CC_CHR) != '\n')) {
  47.     if (!(*p & (CC_NEC|CC_HID))) i++;
  48.     p++;
  49.   }
  50.   go_from(cmcsb._cmcur, p);
  51.   return(p);
  52. }
  53.  
  54.  
  55. int *
  56. goto_beginning_of_line()
  57. {
  58.     int *bp;
  59.     int l,c;
  60.  
  61.     for(bp = cmcsb._cmcur-1; bp > cmcsb._cmbfp; bp--)
  62.     if ((*bp & CC_CHR) == NEWLINE) {
  63.         bp++;
  64.         break;
  65.     }
  66.     go_from(cmcsb._cmcur, bp);
  67.     return(bp);
  68. }
  69.  
  70. goto_current_pos()
  71. {
  72.   int *p;
  73.  
  74.   goto_beginning_of_line();
  75.   for(p = cmcsb._cmbfp; p < cmcsb._cmcur; p++) {
  76.     if (!(*p & (CC_NEC|CC_HID))) 
  77.       cmechx(*p & CC_CHR);
  78.   }
  79. }
  80.  
  81.  
  82. go_up_line(n)
  83. {
  84.     for(; n > 0; n--)
  85.     if (!cmupl()) {            /* then move up to next line */
  86.         cmcr(cmcsb._cmoj);
  87.         cmputc(BS,cmcsb._cmoj);    /* no luck.. try backspace-return */
  88.         cmcr(cmcsb._cmoj);
  89.     }
  90. }
  91.  
  92. go_down_line(n)
  93. {
  94.     for(; n > 0; n--)
  95.     cmdownl();
  96. }
  97.  
  98. int *
  99. go_forward_char(n)
  100. int n;
  101. {
  102.     go_from(cmcsb._cmcur, cmcsb._cmcur + n);
  103.     return(cmcsb._cmcur + n);
  104. }
  105.  
  106. int *
  107. go_backward_char(n)
  108. int n;
  109. {
  110.     go_from(cmcsb._cmcur, cmcsb._cmcur - n);
  111.     return(cmcsb._cmcur - n);
  112. }
  113.  
  114.  
  115. go_backward(n)
  116. int n;
  117. {
  118.     static char *le = NULL;
  119.  
  120.     if (n == cmcsb._cmcol) {
  121.     cmputc('\r', cmcsb._cmoj);
  122.     cmcsb._cmcol = 0;
  123.     }
  124.     else {
  125.     for(; n > 0; n--)
  126.         cmleft();
  127.     }
  128. }
  129.  
  130. go_forward(n)
  131. int n;
  132. {
  133.     static char *le = NULL;
  134.  
  135.     for(; n > 0; n--)
  136.     cmright();
  137. }
  138.  
  139. refresh_eol()
  140. {
  141.     int *cp, *cp1;
  142.     int lines = 0;
  143.     int col;
  144.  
  145.     
  146.  
  147. /* 
  148.  * output the line.  If we wrap, must fix subsequent lines.
  149.  * if we hit a '\n' or the end of the buffer, we can stop.
  150.  */
  151.     for(cp = cmcsb._cmcur; cp< cmcsb._cmptr + cmcsb._cminc; cp++) {
  152.     if (!(*cp & (CC_NEC|CC_HID))) {
  153.         if ((*cp & CC_CHR) == NEWLINE && lines == 0)
  154.         break;
  155.         cmechx(*cp);
  156.         if (cmcsb._cmcol == 0) {    /* wrap point? */
  157.         lines++;        /* count the line */
  158.         }
  159.     }
  160.     }
  161.     go_from(cp, cmcsb._cmcur);
  162. }
  163.  
  164.  
  165. /* relcharpos
  166. **
  167. ** Purpose:
  168. **   Compute line and column position of end, relative to start.
  169. **   if start is cmcsb._cmbfp, include the prompt.
  170. **
  171. ** Input parameters:
  172. **   start, end: start and endpoints of the search
  173. **
  174. ** Output parameters:
  175. **   lpos - Number of lines from the one containing the beginning of the
  176. **     prompt string.
  177. **   cpos - Column position (0 = left edge of screen).
  178. **/
  179. relcharpos(lpos,cpos,start,end)
  180. int *lpos,*cpos,*start,*end;
  181. {
  182.     int sl, sc, el, ec;
  183.  
  184.     if (cmcsb._cmoj == NULL) {        /* not outputting anyway */
  185.     *lpos = *cpos = 0;        /* so don't do anything */
  186.     }
  187.     else {
  188.     abscharpos(start, &sl, &sc);
  189.     abscharpos(end, &el, &ec);
  190.     *lpos = el - sl;
  191.     *cpos = ec - sc;
  192.     }
  193. }
  194.  
  195. abscharpos(ptr, lpos, cpos)
  196. int *ptr;
  197. int *lpos, *cpos;
  198. {
  199.   int count;                /* counts characters */
  200.   int *cp,cc;                /* for scanning buffer characters */
  201.   char c;
  202.  
  203.   count = strlen(cmcsb._cmrty);        /* get length of prompt string */
  204.   *lpos = count / (cmcsb._cmcmx);    /* compute prompt end coordinates */
  205.   *cpos = count % (cmcsb._cmcmx);
  206.                     /* get # of buffer chars to count */
  207.   cp = cmcsb._cmbfp;            /* point to buffer start */
  208.   while (cp < ptr) {            /* loop through chars */
  209.     c = (cc = *cp++) & CC_CHR;        /* get next char */
  210.     if (cc & CC_NEC)
  211.       continue;                /* non-echoed char... no count */
  212.     else if (c == NEWLINE) {
  213.       (*lpos)++;            /* newline... move to next line */
  214.       *cpos = 0;            /* and reset column counter */
  215.     }
  216.     else if (c == TAB) {        /* TAB character */
  217.       *cpos = 8 + 8*(*cpos / 8);    /* move col to next multiple of 8 */
  218.     }
  219.     else {
  220.       if ((c == DELETE) || (c < SPACE)) /* other control char */
  221.         *cpos += 2;            /* count up-arrow and print char */
  222.       else                /* normal printing char */
  223.         (*cpos)++;            /* count it */
  224.     }
  225.     if (*cpos >= cmcsb._cmcmx) {    /* wrap if necessary */
  226.       (*lpos)++;            /* to next line */
  227.       *cpos = 0;            /* column zero */
  228.     }
  229.   }
  230. }
  231.  
  232. int*
  233. disp_forward_char(n)
  234. int n;
  235. {
  236.     int *p = cmcsb._cmcur;
  237.  
  238.     for(; n > 0; n--,p++)
  239.     if (!(*p & (CC_NEC | CC_HID)))
  240.         cmechx(*p & CC_CHR);
  241.     return(p);
  242. }
  243.